import java.io.File;
import java.util.Scanner;

/**
 * main()方法的方法签名：
 * public static void main(String[] args) {...}
 * 下面详细讲解main()方法为什么采用这个方法签名。
 * <p>
 * ➢ public修饰符：Java类由JVM调用，为了让JVM可以自由调用这个main()方法，所以使用public修饰符把这个方法暴露出来。
 * ➢ static修饰符：JVM调用这个主方法时，不会先创建该主类的对象，然后通过对象来调用该主方法。
 * JVM直接通过该类来调用主方法，因此使用static修饰该主方法。
 * ➢ void返回值：因为主方法被JVM调用，该方法的返回值将返回给JVM，这没有任何意义，因此main()方法没有返回值。
 * <p>
 * 运行：java 主类 命令行参数1 命令行参数2 ...
 * java Test Java Spring
 */
class ArgsTest {
    static void test(String[] args) {
        System.out.println(args.length);
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

/**
 * 使用Scanner获取键盘输入
 * 使用Scanner类可以很方便地获取用户的键盘输入，Scanner是一个基于正则表达式的文本扫描器，
 * 它可以从文件、输入流、字符串中解析出基本类型值和字符串值。
 * Scanner类提供了多个构造器，不同的构造器可以接收文件、输入流、字符串作为数据源，用于从文件、输入流、字符串中解析数据。
 * Scanner主要提供了两个方法来扫描输入。
 * ➢ hasNextXxx()：是否还有下一个输入项，其中Xxx可以是Int、Long等代表基本数据类型的字符串。
 * 如果只是判断是否包含下一个字符串，则直接使用hasNext()。
 * ➢ nextXxx()：获取下一个输入项。Xxx的含义与前一个方法中的Xxx相同。
 * 在默认情况下，Scanner使用空白（包括空格、Tab空白、回车）作为多个输入项之间的分隔符。
 * 下面程序使用Scanner来获得用户的键盘输入。
 */
class ScannerKeyBoardTest {
    static void test() {
        Scanner sc = new Scanner(System.in);
        // 增加下面一行将只把回车作为分隔符
//        sc.useDelimiter("\n");
        // 判断是否还有下一个输入项
        while (sc.hasNext()) {
            // 输出输入项
            System.out.println("键盘输入的内容是：" + sc.next());
        }
    }
}

/**
 * Scanner的读取操作可能被阻塞（当前执行顺序流暂停）来等待信息的输入。
 * 如果输入源没有结束，Scanner又读不到更多输入项时（尤其在键盘输入时比较常见），Scanner的hasNext()和next()方法都有可能阻塞，
 * hasNext()方法是否阻塞与和其相关的next()方法是否阻塞无关。
 * 为Scanner设置分隔符使用useDelimiter(String pattern)方法即可，该方法的参数应该是一个正则表达式，关于正则表达式的介绍请参考本章后面的内容。
 * 只要把上面程序中粗体字代码行的注释去掉，该程序就会把键盘的每行输入当成一个输入项，不会以空格、Tab空白等作为分隔符。
 * 事实上，Scanner提供了两个简单的方法来逐行读取。
 * ➢ boolean hasNextLine()：返回输入源中是否还有下一行。
 * ➢ String nextLine()：返回输入源中下一行的字符串。
 * Scanner不仅可以获取字符串输入项，也可以获取任何基本类型的输入项，如下程序所示。
 */
class ScannerLongTest {
    static void test() {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLong()) {
            System.out.println("键盘输入的内容是：" + sc.nextLong());
        }
    }
}

/**
 * 正如通过hasNextLong()和nextLong()两个方法，Scanner可以直接从输入流中获得long型整数输入项。
 * 与此类似的是，如果需要获取其他基本类型的输入项，则可以使用相应的方法。
 * <p>
 * 注意：上面程序不如ScannerKeyBoardTest程序适应性强，因为ScannerLongTest程序要求键盘输入必须是整数，否则程序就会退出。
 * <p>
 * Scanner不仅能读取用户的键盘输入，还可以读取文件输入。
 * 只要在创建Scanner对象时传入一个File对象作为参数，就可以让Scanner读取该文件的内容。
 * 例如如下程序。
 */
class ScannerFileTest {
    static void test() throws Exception {
        Scanner sc = new Scanner(new File("test.txt"));
        System.out.println("test.txt文件内容如下：");
        while (sc.hasNextLine()) {
            System.out.println(sc.nextLine());
        }
    }
}

/**
 * 因为上面程序涉及文件输入，可能引发文件IO相关异常，故主程序声明throwsException表明main方法不处理任何异常。
 */

public class Test {
    public static void main(String[] args) throws Exception {
        ArgsTest.test(args);
//        ScannerKeyBoardTest.test();
//        ScannerLongTest.test();
        ScannerFileTest.test();
    }
}
